package cn.mrcode.wxsdk.web.common;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URLEncoder;

/**
 *微信网页授权 链接生成
 * @author zq
 * @version V0.1
 * @date 2015年1月6日 上午10:18:08
 */
public class AuthorizeUrl {
    private static Logger log = LoggerFactory.getLogger(AuthorizeUrl.class);;
	/**
	 * 微信授权的接口地址
	 */
	public static final String WX_OAUTH2_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?";
	/** （不弹出授权页面，直接跳转，只能获取用户openid） **/
	public static final String SCOPE_SNSAPI_BASE= "snsapi_base";
	/** （弹出授权页面，可通过openid拿到昵称、性别、所在地。并且，即使在未关注的情况下，只要用户授权，也能获取其信息） **/
	public static final String SCOPE_SNSAPI_USERINFO= "snsapi_userinfo";

	/** 无论直接打开还是做页面302重定向时候，必须带此参数  **/
	private final String wechat_redirect = "#wechat_redirect";
	/**  返回类型 固定值**/
	private final String response_type = "code";

	private String appid; //开发者帐号id
	private String redirect_uri;  //点击菜单后，需要跳转的页面地址
	private String scope; //授权范围
	private String state; //重定向后会带上state参数，开发者可以填写a-zA-Z0-9的参数值


	private AuthorizeUrl(ConcreteBuilder concreteBuilder) {
		super();
		this.appid = concreteBuilder.appid;
		this.redirect_uri = concreteBuilder.redirect_uri;
		this.scope = concreteBuilder.scope;
		this.state = concreteBuilder.state;
	}

    /**
     * 创建本方法之前 需要先调用builder
     * @return
     */
	public String createUrl(){
		//@formatter off

		// 微信的 state 属性有问题，所以永远不填写该属性，把该属性作为参数增加到目标跳转页
		/*if (StringUtils.isNotBlank(this.state)) {
			this.redirect_uri += "id=" + this.state + "&appid=" + this.appid;
		}*//*else {
			this.redirect_uri += "&appid=" + this.appid;
		}*/

        try {
            StringBuffer result = new StringBuffer(AuthorizeUrl.WX_OAUTH2_URL).
                    append("appid=").append(this.appid)
                    .append("&redirect_uri=").append(URLEncoder.encode(this.redirect_uri, "UTF-8"))
                    .append("&response_type=").append(this.response_type)
                    .append("&scope=").append(this.scope);

            //@formatter on
            if(this.state != null){
                result.append("&state=").append(this.state);
            }
            result.append(this.wechat_redirect);
            return result.toString();
        }catch (Exception e){
            log.error(e.getMessage());
        }
        return null;
	}


	public static class ConcreteBuilder{
		private String appid;
		private String redirect_uri;
		private String scope;
		private String state;
		/**
		 *
		 * <p>Title: </p>
		 * <p>Description:必须的参数 </p>
		 * @param appid 开发者账户id
		 * @param redirect_uri 在微信点击菜单或则连接后 跳转的页面地址,后面一定要加问号：如：http:/www.zq.com/wen.html?
		 * @param scope 跳转范围，SurverMenuUrl 类中有静态常量选择
		 *
		 * @version V0.1
		 * @date 2015年1月6日 上午9:53:38
		 */
		public ConcreteBuilder(String appid, String redirect_uri, String scope) {
			super();
			this.appid = appid;
			this.redirect_uri = redirect_uri;
			this.scope = scope;
		}
		/**
		 *
		 * @Title: setState
		 * @Description: 选填的数据，业务值：(建议不传递该参数。需要什么参数自己在url后面以参数的形式传递)<br>
		 * 重定向后会带上state参数，开发者可以填写a-zA-Z0-9的参数值 ，此参数，微信接口有问题，重定向后
		 * 不会带上state参数，但是会把此设置的value追加到 目标地址后面
		 * @param state
		 * @return ConcreteBuilder
		 *
		 * @version V0.1
		 * @date 2015年1月6日 上午9:56:18
		 */
		public ConcreteBuilder setState(String state) {
			this.state = state;
			return this;
		}

		/**
		 *
		 * @Title: builder
		 * @Description: 构建正真的对象，返回
		 * @return SurverMenuUrl
		 *
		 * @version V0.1
		 * @date 2015年1月6日 上午10:00:15
		 */
		public AuthorizeUrl builder() {
			if(StringUtils.isBlank(appid)) {
				throw new IllegalArgumentException("开发者账户id不能为空！");
			}
			if(StringUtils.isBlank(redirect_uri)) {
				throw new IllegalArgumentException("跳转的页面链接地址不能为空！");
			}
			if(StringUtils.isBlank(scope)){
				throw new IllegalArgumentException("授权范围不能为空！");
			}
			return new AuthorizeUrl(this);
		}

	}
}
